perm filename SUPDUP.MID[NET,MRC]2 blob
sn#303941 filedate 1977-09-07 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00038 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00004 00002 Assembly options, etc.
C00007 00003 AC's, I/O channels, macros
C00009 00004 SUPDUP documentation
C00012 00005 SUPDUP FEATURES:
C00016 00006 Mappings between ITS and SAIL ASCII
C00019 00007 Data area
C00022 00008 Display crufties
C00025 00009 More display data stuff
C00027 00010 ITS TTY definitions
C00031 00011 ITS output buffer codes
C00033 00012 Interrupt and UUO service
C00037 00013 Startup, etc.
C00040 00014 Monitor command processor
C00042 00015 Get host name
C00045 00016 ICP ICP ICP
C00048 00017 (continued from previous page)
C00051 00018 Final pre-display initialization
C00053 00019 Slurp up and send terminal ID
C00055 00020 Now check to see if we have a reasonable match
C00058 00021 Main program loop, clock interrupt
C00060 00022 TTY input service
C00062 00023 Output a character to the network buffer in the hairy way
C00065 00024 More output mapping stuff
C00069 00025 Network input service
C00073 00026 Subroutines for network input service
C00076 00027 Display hacking
C00079 00028 Display subroutines
C00083 00029 Non-insert/delete display subroutines
C00087 00030 Line insert/delete
C00090 00031 Character insert
C00093 00032 Character delete
C00095 00033 Display update subroutines
C00098 00034 More display updating stuff
C00100 00035 SUPDUP commands
C00103 00036 More SUPDUP commands stuff
C00107 00037 Screen record crock
C00111 00038 Random routines, literals, etc.
C00114 ENDMK
C⊗;
subttl Assembly options, etc.
title SUPDUP User for Data Discs
; Mark Crispin, SU-AI, September 1977
; This is the SAIL implementation of the ITS SUPDUP program, which
; is used for display communication across ITS systems.
if1 .insrt MACROS[1,MRC]
nd. icpskt==137 ; new SUPDUP ICP socket
nd. pdllen==50 ; length of pushdown stack
nd. nlines==38. ; number of lines on screen
nd. linel==83. ; line length used by ITS
nd. nlnglt==1 ; number of lines to glitch when scrolling
nd. nsclin==5. ; number of seconds for clock interrupt
nd. nlnupd==4. ; number of lines that cause screen update
; instead of updating individual lines
swdef. [debugp==0]Set ≠ 0 if to beep on a warning, <0 if to halt as well
nchars==<<<linel+5>/5>*5> ; number of characters per line, must
; be a multiple of 5 for display stuff
; to win
if2,[ ; SWPRINT not defined until after next page
swprint \pdllen,words of PDL storage.
swprint \icpskt,is the ICP socket.
radix 10. ; print these in decimal
swprint \nlines,lines on the screen.
swprint \linel,characters per line.
swprint \nlnglt,lines per glitch when scrolling.
swprint \nlnupd,minimum lines changed to cause full screen update.
swprint \nsclin,seconds between clock interrupts.
radix 8. ; back to octal
]
subttl AC's, I/O channels, macros
; Accumulators
; I is an interrupt level AC and may not be used anywhere else. Things
; depend on the order of X, Y, Z, and A being consecutive. U is used at
; UUO level. U, V, and W are also used in IMP status interrupts and must
; be consecutive.
acdef. [x y z a b c i u v w]
; I/O channels
; ICP is used for ICP'ing only, NET is the general network work channel,
; DSK is only used for reading ROOMS[P,DOC] and for recording the screen.
acdef. [icp net dsk]
.hkill icp net dsk ; so DDT doesn't confuse these
; with AC's on typeout
; Macros
; Print out switch settings
define swprint value,line/
printx/value line
/
termin
; Map character in ac to char2 if it contains char1 now
define mapit ac,char1,char2
caxn ac,char1
jrst [movx ac,char2
return]
termin
; Generate a Data Disc command
define ddcmd o1,d1,o2,d2,o3,d3
.byte 8.,8.,8.,3.,3.,3.,3.
d1 ? d2 ? d3 ? o1 ? o2 ? o3 ? 4
.byte
termin
subttl SUPDUP documentation
COMMENT ⊗
SUPer-DUPer Display TELNET to ITS
Mark Crispin
INTRODUCTION:
SUPDUP is the SAIL implementation of the ITS SUPDUP program, which
is used for TELNETing between ITS sites. This program uses the
internal ITS display codes for highly efficient communication and
full use of ITS display programs over the ARPAnet. It runs on Data
Discs only.
When SUPDUP is run, it will prompt for the host name. Type one or
two characters to identify the name of the ITS system you wish to
TELNET to (ie, either "A", "D", "MC", and "ML"). SUPDUP will then
establish a connection with the specified ITS site, and after that
you will effectively be a display on ITS, with full bucky bit
capability.
Some mappings in input and output are made due to the differences
between the SAIL and ITS ASCII character sets. Most of these mappings
are transparent to the user. The design philsophy behind the mappings
was to cause characters typed on the Stanford keyboard to be seen by
ITS as the character appears on the key tops, and for characters
received from ITS to be displayed as they would be at a console at MIT.
NOTE!!!:
One thing that I should mention: you MUST NOT do a :TCTYP on ITS that
will set your terminal type. SUPDUP's operation depends upon the
terminal type being SOFTWARE and things will not work correctly if
it is set to anything else. It is alright to set certain other TCTYP
options such as SAIL character set enable, however, in general you
probably will not want to do any TCTYP at all. SUPDUP sets the line
length and page size to the maximum possible on the screen.
SUPDUP FEATURES:
Visible OUTPUT MAPPINGS:
Caret is mapped to AND sign (∧) since there is no code in the SAIL
character set for caret. There is no way to tell between AND sign and
caret.
Visible INPUT MAPPINGS:
αz and αZ are mapped to [CALL], αβz and αβZ are mapped to α[CALL];
α_ is mapped to [BACK NEXT] and αβ_ is mapped to β[BACK NEXT]. ↑ is
mapped to caret. VT will send the uparrow character, but without the
[TOP] bit; there is no way to send the [TOP]ified ↑ other then by using
[BACK NEXT]4013. Also, there is no way to send β[CALL] or αβ[CALL] other
than by using [BACK NEXT]432 and [BACK NEXT]632.
COMMANDS:
[ESCAPE]I is used to enter a SUPDUP command. The following commands
are defined:
F Use Fast display mode (discussed below).
H Type a help text.
K Kill the job on ITS and break network connections.
L Same as K command.
P Temporarily restore the page printer. Typing any
character will return your screen to ITS.
Q Quit out, close network connections, detach the job
on ITS if there is one.
R Record contents of screen onto a file; asks you for
name of file to write.
S Use Slow display mode (see below).
? Same as H.
In addition, in [ESCAPE]I mode, αz, αβz, αZ, αβZ, α_, and αβ_ are
sent as themselves without being mapped. Maybe someday if β[CALL]
and αβ[CALL] become readable by a program then the mappings on z's will
be removed. [My suggestion that this be done has been rejected however.]
DISPLAY MODES:
SUPDUP has two display modes; fast and slow, which are set by the F and S
commands. Fast mode, which is the default, is highly optimal on network
input and very fast on display. On the other hand, it can be disconcerting
to have the screen flash as suddenly as it does with no semblance of line-
per-line output (it sort of comes out as chunk-per-chunk), therefore, there
is a slow mode which causes SUPDUP to output in the old-fashioned manner
which just does normal optimization but not line/screen optimization.
⊗
subttl Mappings between ITS and SAIL ASCII
; Everything nobody wanted to know about SUPDUP's internal mappings...
; The following character set mappings are in effect. These mappings occur
; on both input and output, so in general they are invisible to the user. In
; particular, the graphic on the keytop is what ITS will see, and what is
; displayed on the screen is what would be displayed on an ITS TV. But see
; the second table and notes for exceptions.
; SAIL ITS
; ---- ---
;
; 011 TAB INT (1)
;
; 013 VT ↑
;
; 030 _ ←
;
; 032 ~ ≠
;
; 033 ≠ ALT
;
; 136 ↑ ∧ (2)
;
; 137 ← _
;
; 175 ALT }
;
; 176 } ~
; In addition, the following keyboard mappings are done:
; KBD code Sent to ITS
; --- ---- ---- -- ---
;
; αz [CALL] (3)
;
; αZ [CALL]
;
; αβz α[CALL]
;
; αβZ α[CALL]
;
; α_ [BACK NEXT] (4)
;
; αβ_ α[BACK NEXT]
;
; ↑ ∧ (2) (5)
; Notes:
;
; (1) This character is image tab, which on a PDP-11 TV is output as
; integral sign.
;
; (2) AND sign (∧) is used for caret since there is no code in the SAIL
; character set for caret anyway.
;
; (3) These four mappings are necessary since there is no way that any
; form of [CALL] can be read by a user program. Perhaps if metized
; [CALL]'s are allowed things will change.
;
; (4) This mapping is necessary since there is no key remotely equivalent
; to the [BACK NEXT] key.
;
; (5) This mapping is necessary since otherwise there is no way to enter
; caret from the keyboard. As caret is more important on ITS, up
; arrow lost. VT will input an up-arrow, however it will not be
; [TOP]ified, meaning that in order to enter this character into TECO
; one must use a quoting convention.
subttl Data area
; Beginning of core area initialized to zero at startup
tmploc 41,jsr uuoser ; UUO server
corbeg==. ; relocatable zero
cnsblk: ; CNSGET info
tctyp: block 1 ; TCTYP for server
ttyopt: block 1 ; TTYOPT for server
tcmxv: block 1 ; TTY page length
tcmxh: block 1 ; TTY width
cnsrol: block 1 ; CNSROL variable
cnsbll==.-cnsblk
; Random flags
filinp: block 1 ; -1 → fill in host name
runcmp: block 1 ; -1 → called via RUN command
slowip: block 1 ; -1 → do input slow way
; Interrupt pending flags
ttiinp: block 1 ; -1 → TTI pending
ntoinp: block 1 ; <0 → INS pending
ntiinp: block 1 ; -1 → NTI pending
escpip: block 1 ; -1 → <ESCAPE>I typed
imgchp: block 1 ; -1 → image αz, αβz, αZ, αβZ, α_, αβ_
; Buffer headers
ntibf: block 3 ; net input buffer header
ntobf: block 3 ; net output buffer header
dsibf: block 3 ; disk input buffer header
; Other random storage
lgrskt: block 1 ; socket from logger
pdl: block pdllen ; pushdown stack
; These two locations must be in this order!!
mskbts: block 1 ; interrupt bits to go on
retnpc: block 1 ; PC to return to
; IMP MTAPE command words
; Connect to host command block
impcod: block 1 ; command
impsta: block 1 ; status
implsk: block 1 ; local socket
impwat: block 1 ; ≠ 0 → wait for connection
impbyt: block 1 ; byte size
impfsk: block 1 ; foreign socket
imphst: block 1 ; foreign host number
; Wait for connection to be completed command block
watcod: block 1 ; command
watsta: block 1 ; status
watskt: block 1 ; socket
; Close connection to host command block
clscod: block 1 ; close code
clssta: block 1 ; close status
clsskt: block 1 ; close socket
clswat: block 1 ; ≠ 0 → wait for close
subttl Display crufties
; Number of words in display frobs
nwrdln==4+nchars/5 ; number of words on a line
scrsiz==nlines*nwrdln ; number of words on screen
ngw==<<nchars*3>+17.>/16. ; number of graphics words
; Cursor position pointers
vpos: block 1 ; vertical position
hpos: block 1 ; horizontal position
ovpos: block 1 ; old vertical position
; Positioning flags
govpos: block 1 ; -1 → get old vertical position
gohpos: block 1 ; -1 → get old horizontal position
gtvpos: block 1 ; -1 → get vertical position
gthpos: block 1 ; -1 → get horizontal position
; Insert/delete mode flags
gtiln: block 1 ; -1 → get # of lines to insert
gtdln: block 1 ; -1 → get # of lines to delete
gtich: block 1 ; -1 → get # of characters to insert
gtdch: block 1 ; -1 → get # of characters to delete
; Screen updating flags
slupdp: block nlines ; -1 → this line has changed
scupdp: block 1 ; -1 → some update happened someplace
saupdp: block 1 ; -1 → updated whole screen
crupdp: block 1 ; -1 → updated cursor
corend==.-1 ; address of top of core
; End of core zeroed upon startup
; Various display programs
; Erase screen display program
sce: ddcmd 1,17,1,17,2,0 ; erase screen
0 ; all done
scel==.-sce
; Display screen display program
scp: ddcmd 1,46,4,1,5,10 ; line address 30
ddcmd 3,2,3,2,3,2 ; go to column 2
screen: block scrsiz ; TV screen storage
scrend=.-1 ; end of screen storage
0 ; end of DD program
scpl==.-scp
botlin=screen+scrsiz-nwrdln+2-1 ; address of start of bottom line
; Display cursor display program
scc: ddcmd 1,7,1,7,1,7 ; graphics
ddcmd 3,1,4,0,5,0 ; select position
block ngw ; all graphics columns
ddcmd 0,0,1,46,1,46 ; execute
0 ; end of program
sccl==.-scc
; More display data stuff
; Display commands
; Clear screen
sclear: sce ; address of display program
scel ; size of display program
0 ? 0 ; no t-in-p flag, line command addr
; Display screen
sdisp: 200000,,scp ; two field mode
scpl ; size of display program
0 ; no transfer in progress flag
scp ; address of low order line command
; Cursor display
cdisp: scc ; address of cursor hacker
sccl ; size of the hacker
0 ; no transfer in progress flag
scc+1 ; address of low order line command
; Line display
ldisp: 200000,,0 ; two field mode
nwrdln ; size of this command
0 ? 0 ; no t-i-p flag, l.c.a. gets hacked
; Byte pointer table for insertions
scbytp: 350700,,(y)
260700,,(y)
170700,,(y)
100700,,(y)
010700,,(y)
subttl ITS TTY definitions
; These definitions are the various bits, words, etc. from the
; ITS TTY system calls and are here for convenience and clarity
; TTYOPT variable (terminal capabilities)
%toalt==200000,, ; 1 → standardise altmodes
%toclc==100000,, ; 1 → convert cases on input
%toers==040000,, ; 1 → this terminal can erase
%tohdx==020000,, ; 1 → half duplex
%tomvb==010000,, ; 1 → can backspace
%tosai==004000,, ; 1 → has SAIL graphics
%tosa1==002000,, ; 1 → use SAIL graphics
%toovr==001000,, ; 1 → can overprint
%tomvu==000400,, ; 1 → can line starve (ie a display)
%tomor==000200,, ; 1 → do **More** processing
%torol==000100,, ; 1 → scroll instead of wraparound
%toraw==000040,, ; 1 → no cursor motion optimization
%tolwr==000020,, ; 1 → lower case keyboard
%tofci==000010,, ; 1 → has bucky bit keyboard
%toiml==000004,, ; 1 → acts like a grIMLAC
%tolid==000002,, ; 1 → can insert/delete lines
%tocid==000001,, ; 1 → can insert/delete characters
%tpplf==700000 ; LF padding
%tppcr==070000 ; CR padding
%tpptb==007000 ; TAB padding (0 → no tabs, 1 → tabs)
%tptel==000100 ; 1 → CR → CRLF for ARPAnet protocol
%tpcbs==000040 ; 1 → intelligent terminal protocol
%tp11t==000020 ; 1 → PDP-11 TV
%tpors==000010 ; 1 → output reset should do something
%tpibc==000002 ; 1 → correspondence code 2741
%tpibm==000001 ; 1 → IBM 2741
; TTYOPT bits for a Data Disc
ddbits==%toers\%tomvb\%tosai\%tosa1\%tomvu\%tomor\%tolwr\%tofci\%tolid\%tocid
ddbits==ddbits\%tpcbs\%tpors
; TCTYP variable (terminal type)
%tnprt==0 ; printing console, glass TTY, etc.
%tndp==1 ; good Datapoint
%tnodp==2 ; inferior losing Datapoint
%tniml==3 ; grIMLAC
%tntek==4 ; Tektronix 4000 series
%tntv==5 ; PDP-11 TV
%tnmem==6 ; Memowreck
%tnsfw==7 ; Software
%tntrm==10 ; Terminet
%tnesc==11 ; ASCII standard display (VT52, etc.)
%tndtm==12 ; Datamedia 2500
; Bucky bits
%txctl==0200 ; control
%txmta==0400 ; meta
%txsft==1000 ; shift
%txsfl==2000 ; shift lock
%txtop==4000 ; top
subttl ITS output buffer codes
; These are the ITS output buffer codes (used by Software terminals).
%tdmov==200 ; move cursor OV OH NV NH
%tdmv1==201 ; impossible; NV NH
%tdeof==202 ; clear to end of screen
%tdeol==203 ; clear to end of line
%tddlf==204 ; delete character after cursor
%tdmtf==205 ; motor off
%tdmtn==206 ; motor on
%tdcrl==207 ; terpri
%tdnop==210 ; no-op
%tdbs==211 ; backspace
%tdlf==212 ; line feed
%tdrcr==213 ; carriage return
%tdors==214 ; output reset
%tdqot==215 ; ???
%tdfs==216 ; cursor forward
%tdmv0==217 ; move cursor NV NH
%tdclr==220 ; clear screen
%tdbel==221 ; feep!
%tdini==222 ; reset reset reset
%tdilp==223 ; insert line
%tddlp==224 ; delete line
%tdicp==225 ; insert character
%tddcp==226 ; delete character
%tdbow==227 ; inverse video
%tdrst==230 ; reset inverse video, etc.
subttl Interrupt and UUO service
; UUO server. Only allows BURP UUO (op code 037). If DEBUGP≠0, beep as well,
; and if DEBUGP<0, halt too.
BURP=037000,, ; UUO for logging cruft
uuoser: 0 ; called via JSR, last impure location(!!)
ldb u,[331100,,40] ; get op code
caxe u,burp←-27. ; was it a BURP UUO?
jrst [ outstr [asciz/Illegal UUO!/]
jrst 4,.-1] ; glork!
outstr @40 ; type the message
ifn debugp,[
movx u,%fword ; this console
beep u, ; feep!
ifl debugp,jrst 4,.+1 ; if super paranoia mode set
]
jrst 2,@uuoser ; return to user
; Interrupt server
; Interrupt condition bits
inttty==020000,, ; TTY input activation
intclk==000200,, ; clock interrupt
intins==000040,, ; IMP INS
intims==000020,, ; IMP status change
intinp==000010,, ; IMP input waiting
inttti==000004,, ; <ESCAPE>I
; Nothing is done at interrupt level other than to determine the
; cause of the interrupt and set bits for the main program level
; to use. This is because SAIL interrupt service is nothing like
; ITS interupt service and you can only be at interrupt for 8
; jiffies and system calls will foul up in general and so on,
; unlike ITS user TELNET which can spend large amounts of time at
; interrupt level without harm.
intser: skipn i,jobcni ; get reason for interrupt
jrst 4,.-1 ; spurious interrupt?
txze i,inttty ; got a character?
store %fword,ttiinp ; yup, TTI on on on
txz i,intclk ; just ignore clock interrupts
txze i,intins ; IMP INS?
sos ntoinp ; yes, flag net output interrupt
txze i,intinp ; IMP input?
store %fword,ntiinp ; yup, flag IMP input
txze i,inttti ; <ESCAPE>I?
store %fword,escpip ; yup, command time
txze i,intims ; IMP status change?
jrst netser ; yes, hack net status change
luzint: jumpn i,[ outstr [asciz/Spurious interrupt!
/]
jrst 4,.] ; funny interrupt bit?
dismis ; yes, dismiss interrupt
; Network status interrupt. Find out what happened and maybe die.
netser: xct luzint ; check for garbage
move u,jobtpc ; get PC at the interrupt
movem u,retnpc ; save it as return PC
store %fword,mskbts ; all masking bits
imskcl mskbts ; go off
uwait ; finish up any UUO in progress
debreak ; leave interrupt level
movx u,2 ; get status
mtape net,u ; get network status
ior v,w ; merge status bits together
txne v,(60000) ; connection closed?
jrst diedie ; lose lose
intdej mskbts ; sigh, well, hurry on back
subttl Startup, etc.
; Initialize the world; clear all I/O and other things; give
; back any unneeded core to the monitor; clear data area, and
; set up the stack pointer.
supdup: jfcl ; flush CCL crufties
reset ; reset all I/O
ifn debugp,[
outstr [asciz/
Warning!! This is a debugging version/]
ifl debugp,outstr [asciz/ with breakpoints and may stop at any time/]
outstr [asciz/!!
/]
]
movei intser ; get addr of interrupt server
movem jobapr ; tell monitor
hlrz jobsa ; get size I should be
movem jobff ; make sure monitor knows
core ; in case I grew
jfcl ; you ingrate!
store %zeros,corbeg,corend ; zak!
move p,[pdl(-pdllen)] ; load PDP
; Check terminal characteristics; this program will only work
; on a Data Disc.
movx x,%fword ; my console
getlin x ; get my line characteristics
caxn x,%fword ; detached?
exit ; yes, die die die
txnn x,(20000) ; is this a Data Disc?
jrst [ outstr [asciz/SUPDUP only runs on Data Discs./]
exit] ; maybe DM and/or III someday
; Set terminal modes; no echo and activate on all characters
ptjobx [0 ? sixbit/DOFF/] ; turn echoing off
txo x,(100) ; special activation mode bit
setlin x ; enter SAM
setact [[777777,,777777 ; activate on 000 - 043
777777,,777777 ; 044 - 107
777777,,777777 ; 110 - 153
777777,,600066]] ; 154 - 177, αβ activate, etc
; Set up terminal codes for ITS and the sort of display we are
store %tnsfw,tctyp ; software TTY
store ddbits,ttyopt ; what we can support
store nlines,tcmxv ; vertical screen size
store linel,tcmxh ; horizontal screen size
store nlnglt,cnsrol ; number of lines to glitch
subttl Monitor command processor
; Check for host name in the monitor command line. Yes, I realize this
; code is totally wierd!!!
rescan x ; get monitor command cruft back
jumpe x,gethst ; no cruft, ask for it
moncom: inchrs x ; got a command, gobble a character
jrst gethst ; lost, do it manually
caxl x,"a ; lower case?
txz x,<" > ; yes, uppercaseify
skipn runcmp ; already checked for RUN command?
jrst [ caxe x,"R ; is it a RUN command?
aosa runcmp ; nope
store %fword,runcmp ; yes, no spaces checked!
jrst .+1] ; now return
skipl runcmp ; called via RUN command?
caxe x,<" > ; space frob? (only if not RUN)
caxn x,<";> ; or comment?
caxa ; yup, hack it
jrst moncom ; haven't gotten there yet, try again
move b,[jsp y,[ inchrs x ; yes, load subroutine
jrst badhst ; lost
caxl x,"a ; lower case?
txz x,<" > ; yes, uppercaseify
caxn x,<" > ; found space?
jrst -1(y) ; yes, flush it
jrst (y)]] ; end of subroutine
jrst scnhst ; and scan for this host
subttl Get host name
gethst: outstr [asciz/Host = /]
move b,[jsp y,[ inchrw x ; subroutine for non-monitor command
caxl x,"a ; lower case?
txz x,<" > ; yes, uppercaseify
outchr x ; echo the whatever
jrst (y)]] ; end of non-monitor subroutine
store %fword,filinp ; remember to fill in host name
scnhst: xct b ; get a character
caxn x,"A ; AI Lab?
jrst [ skipe filinp ; fill in host name?
outchr ["I] ; yes
movx a,sixbit/AI/ ; select host name
setnam a, ; and tell monitor
movx a,206 ; MIT-AI
jrst goicp] ; now ICP
caxn x,"D ; Dynamod?
jrst [ skipe filinp ; fill in host name?
outchr ["M] ; yes
movx a,sixbit/DM/ ; select host name
setnam a, ; and tell monitor
movx a,106 ; MIT-DMS
jrst goicp] ; now ICP
caxe x,"M ; MathLab LCS place?
badhst: jrst [ outstr [asciz/?
/]
clrbfi ; flush input buffer
jrst gethst]
xct b ; get another character
caxl x,"a ; lower case?
trz x,<" > ; uppercaseify
caxn x,"C ; MACSYMA consortium?
jrst [ movx a,sixbit/MC/ ; select host name
setnam a, ; and tell monitor
movx a,354 ; MIT-MC
jrst goicp] ; now ICP
caxe x,"L ; Autoprog?
jrst badhst ; nope, losey
movx a,sixbit/ML/ ; select host name
setnam a, ; tell monitor
movx a,306 ; MIT-ML
; jrst goicp ; now ICP
subttl ICP ICP ICP
goicp: clrbfi ; clear any crlf, etc.
outstr [asciz/
Trying... /]
; Open channels and set timeouts
init icp,17 ; open ICP in dump mode
'IMP,, ; ARPAnet
0 ; no buffers
jrst icpluz ; oh well
mtape icp,[ 17 ; set timeouts
.byte 6 ? 2 ? 24 ? 0 ? 7 ? 7 ? 0]
init net,0 ; open NET in ASCII mode
'IMP,, ; ARPAnet
ntobf,,ntibf ; buffers
jrst icpluz ; rather screwy
mtape net,[ 17 ; set timeouts
.byte 6 ? 2 ? 24 ? 0 ? 7 ? 0 ? 0]
; Try to generate a unique socket number, using job number and
; time of day to avoid lossage due to old connections.
; Algorithm used is: job #,,<time&777770>
pjob x, ; get my job #
mstime y, ; and the time now
lsh x,18. ; put job # in LH
hrri x,(y) ; and time in RH
andx x,37777777770 ; but zap low order bits
; Now try to get to the foreign place's server
insirp setzm,[impcod impsta impbyt]
store %fword,impwat ; do wait until timeout
movem x,implsk ; my socket to use
movem x,clsskt ; socket to close when done
movem a,imphst ; host to go to
store icpskt,impfsk ; socket to ICP on
mtape icp,impcod ; connect → foreign logger
move x,impsta ; get status
txnn x,77 ; error code?
statz icp,763600 ; or error bits?
jrst icpluz ; so sorry
txc x,(300000) ; for next instruction to win
txne x,(300000) ; RFC sent+received?
jrst icpluz ; nope, lose
move y,[iowd 1,impfsk] ; get ready to get a word
movx z,%zeros ; stop after
; (continued on next page)
; (continued from previous page)
; Get socket number from logger
in icp,y ; get socket from logger
caxa ; won
jrst [outstr [asciz/Did not get socket number from foreign host!/]
jrst 4,.-2]
move x,impfsk ; load socket we got
lsh x,-4 ; compensate for left justification
movem x,impfsk ; and save it back
store 3,clscod ; close code
mtape icp,clscod ; close off ICP socket
releas icp, ; free up channel
; Got socket number from logger; now connect output
movx x,3 ; ICP/transmit offset
addb x,implsk ; local transmit socket
movem x,watskt ; save wait socket
store %zeros,impwat ; don't wait
store 8.,impbyt ; byte size
mtape net,impcod ; connect → server output
move x,impsta ; get status
txne x,77 ; error code?
jrst icpluz ; lose lose lose
; Now connect input
sos implsk ; local receive socket
aos impfsk ; foreign transmit socket
mtape net,impcod ; connect ← server input
move x,impsta ; get status
txne x,77 ; error code?
jrst icpluz ; lose lose lose
; Now wait until we get the connection
store 4,watcod ; WAIT code
mtape net,watcod ; wait for output
move x,watsta ; get status
txne x,77 ; error?
jrst icpluz ; lose lose lose
sos watskt ; now select receive socket
mtape net,watcod ; wait for input
move x,watsta ; get status
txne x,77 ; error?
jrst icpluz ; lose lose lose
statz net,763600 ; error bits?
jrst icpluz ; too bad
outstr [asciz/Open
/]
subttl Final pre-display initialization
; Random other pre-execution initialization crufties
movx x,8. ; 8 bit bytes you know
dpb x,[300600,,ntibf+1] ; hack input buffer
dpb x,[300600,,ntobf+1] ; and output buffer
movx x,inttty\intclk\intins\intims\intinp\inttti
intenb x, ; enable interrupt conditions
clkint nsclin*60. ; get a clock interrupt every n secs
mtape net,[15 ? 1] ; maximum allocation
outbuf net,4 ; allow for fast typists
; Send terminal characteristics
move z,[440600,,cnsblk] ; load sixbit pointer to TTY chars
movx y,6*cnsbll ; load number of bytes to do
ttchsn: ildb x,z ; get a character
call netoc1 ; output it
sojg y,ttchsn ; loop until done
call netsnd ; now force it out
; Now get server's greeting message
grtmsg: call netich ; get a character from the network
caxn x,%tdnop ; hit the no-op yet?
jrst grtdun ; yes, greeting message done
outchr x ; output it
jrst grtmsg ; and loop for next
; Make sure we can slurp up what is there now due to our hacking
grtdun: store %fword,ntiinp ; will try to slurp slurp slurp now
subttl Slurp up and send terminal ID
; Tell SUPSER to expect terminal name
movx x,300 ; escape to SUPSER
call netoc1 ; send it
movx x,302 ; set TTY id
call netoc1 ; send it
; Now try to get it
open dsk,[0 ? 'DSK,, ? dsibf] ; try to get a DDB
jrst rndtid ; really losing
movx x,sixbit/ROOMS/ ; file name
setzb y,z ; extension, date cruft
movx a,sixbit/ PDOC/ ; PPN
lookup dsk,x ; try to find file
jrst rndtid ; lost
; Compute name we must look for
movx y,('TTY) ; console TTY name
devnum y, ; get our TTY #
jrst rndtid ; losey
idivx y,100 ; siphon off high order digit
idivx z,10 ; and two low order digits
; Now search for TV-...
search: irpc ch,,[TV-]
jsr getch ; get a character
jrst search ; CR can't win
caxe x,"ch ; got it?
jrst search ; not yet
termin
; Now check to see if we have a reasonable match
jsr getch ; get a character for the number
jrst search ; somebody better fix ROOMS[P,DOC] !!
jumpe y,serch1 ; low order terminal
cain x,"0(y) ; win so far?
jsr getch ; get next character
jrst search ; nope, we're still losing
serch1: cain x,"0(z) ; won?
jsr getch ; almost there
jrst search ; nope
caie x,"0(a) ; got a match now?
jrst search ; nope, sorry
; Found the terminal name, now send it along
fndrom: jsr getch ; gobble down spaces
jrst sntrom ; all done I guess
caxn x,<" > ; leading space?
jrst fndrom ; yes, flush it
sndrom: call netoc1 ; send character out
jsr getch ; get a character
jrst sntrom ; all done I guess
caxe x,<" > ; saw a space?
jrst sndrom ; nope, okay to send it
call netoc1 ; well, can send one space
flsspc: jsr getch ; but not any more
jrst sntrom ; all done
caxn x,<" > ; a space to flush?
jrst flsspc ; yes, flush it
sndtid: call netoc1 ; not a space, send it
jsr getch ; get a character
caxa ; all done
jrst sndtid ; no, send it out
; Done with sending room, finish that up and get going on real work
sntrom: movx x,%zeros ; final null
call netoc1 ; send it
tidone: call netsnd ; force the buffer out
release dsk, ; free up channel
; Initialize screen
ppact 0 ; flush PP 0
leypos 2000 ; line editor off screen
ddupg sclear ; zap screen
hrroi x,[004000,,"W] ; restore wholine quickly
ttyset x, ; by doing <ESCAPE>W
call scrini ; init core screen
store %fword,ovpos ; old vertical position
ddupg sdisp ; display the screen
call csrupd ; give a cursor
lock ; now get locked in core
jrst mainlp ; and enter main loop
subttl Main program loop, clock interrupt
; Main program loop
zzzzzz: call scnupd ; update screen if necessary
iwait ; bye bye
; Something woke us up. Find out what
mainlp: call scnupd ; update screen if necessary
aosg escpip ; <ESCAPE>I typed?
jrst cmdcmd ; yes, process command
aosg ttiinp ; TTY input available?
jrst ttiser ; yes, slurp slurp
aosg ntiinp ; network input available?
jrst ntiser ; yes, get network input
; On a clock interrupt we just check the input frobbies to
; make sure we didn't lose an int somehow
inskip ; got a character?
caxa ; nope
jrst ttisr1 ; yes, do it do it do it
mtape net,[10] ; network input?
jrst zzzzzz ; nope
setzm ntiinp ; yes, clear flag if was on
jrst ntiser ; now hack net input
subttl TTY input service
ttiser: inskip ; got a character?
jrst mainlp ; nope, back to main loop
ttisr1: inchrw x ; get a character
ldb y,[000700,,x] ; get ASCII part of X
caxn y,↑M ; terpri?
inchrw y ; gobble line feed
call netoch ; send it out
inskip ; any more?
caxa ; no, force buffer out
jrst ttisr1 ; else hack the extra characters
call netsnd ; send the buffer out
jrst ttiser ; and try for any frobs just came in
; Force the buffer out to the network
netsnd: ldb x,[410300,,ntobf+1] ; load position field
movx y,1 ; get a bit to hack
lsh y,(x) ; 2↑# of characters
subx y,1 ; now get null bit flusher mask
iorm y,@ntobf+1 ; make sure the nulls aren't sent
out net, ; send the character
return ; won
jrst diedie ; lost
; Auxillary NETOCH
netoc1: sosg ntobf+2 ; space available in buffer?
out net, ; no, output the buffer
caxa ; win
jrst diedie ; lose
idpb x,ntobf+1 ; put character in buffer
return ; and return
; Output a character to the network buffer in the hairy way
netoch: sosg ntobf+2 ; space available in buffer?
out net, ; no, output the buffer
caxa ; win
jrst diedie ; lost
aosn imgchp ; image characters?
jrst netoc2 ; yes, don't map then
; Map αZ to [CALL], αβZ to α[CALL], α_ to [BACK NEXT], αβ_ to α[BACK NEXT].
; αz and αβz will behave in a similar manner.
; These mappings are necessary since there is no way that SUPDUP can read a
; [CALL] coming in for the Stanford keyboard. This may someday be changed if
; the system is changed so that a program can see β[CALL] and αβ[CALL]. In
; any case there is no way that either β[CALL] or αβ[CALL] can be sent to ITS
; other than by [BACK NEXT]432 and [BACK NEXT]632 - sorry!
; Note - my suggestion to allow β[CALL] and αβ[CALL] to be read by a program
; has been rejected, so these mappings will stay around.
ldb y,[001000,,x] ; get αcharacter
caxe y,%txctl\"z ; some form of αz?
caxn y,%txctl\"Z ; or of αZ?
jrst [movx y,↑Z ; yes, convert to [CALL]
dpb y,[001000,,x] ; save character
txze x,%txmta ; αβz or αβZ?
iorx x,%txctl ; yes, make it α[CALL]
jrst netoc3] ; now send this bucky command
caxn y,%txctl\"_ ; α_?
jrst [ movx y,↑← ; yes, convert to [BACK NEXT]
dpb y,[001000,,x] ; save character
txze x,%txmta ; αβ_?
iorx x,%txctl ; yes, make it α[BACK NEXT]
jrst netoc3] ; now go send the frob
; jrst netoc2 ; else fall through
; More output mapping stuff
; Map the character from the SAIL to the ITS character set and check for
; if TOPififcation is needed (TECO will treat SAIL graphics as controls
; unless %TXTOP is on). Then check for any bucky bits, and if any, then
; do it the hairy way.
netoc2: ldb y,[000700,,x] ; get ASCII part of character
call outmap ; map to ITS ASCII
dpb y,[000700,,x] ; and kludge back
caxl y,↑J ; LF is not TOPified
caxle y,↑M ; neither are VT, FORM, and CR
caxn y,<↑[> ;]neither is ALT
jrst ntoc2a ; nope, it's a positioning(?) frob
caxge y,<" > ; all SAIL graphics
iorx x,%txtop ; are TOPified (happy TECO)
ntoc2a: txnn x,%txtop\%txsfl\%txsft\%txmta\%txctl; any bucky bits?
jrst [ idpb x,ntobf+1 ; nope, just send the frob
caxn x,"≤ ; sending the escape code?
call netoc1 ; yes, repeat it
return] ; now return
; The character has bucky bits, so the intelligent terminal protocol is used to
; send bucky bits: [↑\] [<bucky bits>←-7] [<character>].
netoc3: movx y,↑\ ; load escape code
idpb y,ntobf+1 ; put character in buffer
movx y,"@ ; initialize bucky word
txze x,%txtop ; [TOP] set?
txo y,%txtop←-7 ; yes, use it then
;
; Nobody in their right mind would write a program on ITS that uses %txsfl and
; %txsft, so it's not worth the runtime to implement.
;
; txze x,%txsfl ; [SHIFT LOCK]?
; txo y,%txsfl←-7 ; uselessness
; txze x,%txsft ; [SHIFT]?
; txo y,%txsft←-7 ; more uselessness
txze x,%txmta ; β character?
txo y,%txmta←-7 ; yup
txze x,%txctl ; α character?
txo y,%txctl←-7 ; yup
exch x,y ; swap swap swap
call netoc1 ; send this cruftie out
exch x,y ; swap back
call netoc1 ; now send the non-bucky character
return ; and return
; Output mapping from SAIL to ITS character set. The idea is that the Stanford
; keyboard appears as a strange type of Knight keyboard.
outmap: mapit y,030,137 ; underscore
mapit y,032,176 ; tilde
mapit y,033,032 ; not equals
mapit y,137,030 ; backarrow
mapit y,175,033 ; diamond
mapit y,176,175 ; right curly bracket
return ; else return
subttl Network input service
ntiser: skiple ntibf+2 ; maybe there is some cruft
jrst ntisr1 ; from before...
ntisr2: mtape net,[10] ; any input available?
jrst mainlp ; no, return
in net, ; yes, get a new buffer
caxa ; won
jrst diedie ; lost
ntisr1: sosge ntibf+2 ; anything in buffer?
jrst ntisr2 ; nope, try another
call nulfls ; flush nulls
ldb x,ntibf+1 ; get a byte
skipge ntoinp ; still hacking output reset?
caxn x,%tdors ; got an output reset?
caxn x,377 ; padding null?
jrst ntisr1 ; sigh
; Check for any display stuff that must be done
aosn govpos ; get old vertical position?
jrst [ store %fword,gohpos ; yes, now get old horizontal position
jrst ntisr1] ; and try for next
aosn gohpos ; get old horizontal position?
jrst [ store %fword,gtvpos ; yes, get vertical position now
jrst ntisr1] ; and try for next
aosn gtvpos ; get vertical position?
jrst [ store %fword,gthpos ; yes, get horizontal position now
movem x,vpos ; save current vpos now
store %fword,crupdp ; flag cursor updated
jrst ntisr1] ; and try for next
aosn gthpos ; get horizontal position?
jrst [ movem x,hpos ; set horizontal position
store %fword,crupdp ; flag cursor updated
jrst ntisr1] ; and continue
aosn gtiln ; insert lines?
jrst inslin ; yup
aosn gtdln ; delete lines?
jrst dellin ; yup
aosn gtich ; insert characters?
jrst inschr ; yup
aosn gtdch ; delete characters?
jrst delchr ; yup
caxle x,177 ; display code?
jrst dpyser ; yes, go do special things
; Check for garbage received and flush it
jumpe x,[ burp [asciz/Spurious input NUL flushed.
/]
jrst ntisr1] ; I think NULs can't happen anymore
caxn x,↑J ; image LF?
jrst [ burp [asciz/Spurious input image LF flushed.
/]
jrst ntisr1] ; should not happen
caxn x,↑M ; image CR?
jrst [ burp [asciz/Spurious input image CR flushed.
/]
jrst ntisr1] ; should not happen
caxn x,177 ; rubout?
jrst [ burp [asciz/Spurious input RUBOUT flushed.
/]
jrst ntisr1] ; this shouldn't happen I think
; Good character, so display it
call inpmap ; map from ITS to SAIL ASCII
call scstor ; store it on the screen
jrst ntisr1 ; continue until this frob empty
; Subroutines for network input service
; Read a character from the network, hanging for it
netich: sosg ntibf+2 ; anything in buffer?
in net, ; nope, get some
caxa ; won
jrst diedie ; lost
call nulfls ; call null flusher crock
ldb x,ntibf+1 ; get a byte
caxn x,377 ; padding null?
jrst netich ; yup
pjrst inpmap ; map from ITS to SAIL ASCII
; Map graphics from ITS extended ASCII to SAIL's extended ASCII.
; First comes mappings which are done going anywhere.
inpmap: mapit x,032,033 ; not equals
mapit x,033,175 ; diamond
mapit x,175,176 ; right curly brace
mapit x,176,032 ; tilde
; These are mappings necessary between SAIL and ITS ASCII
mapit x,011,013 ; integral sign
mapit x,013,136 ; uparrow
mapit x,030,137 ; left arrow
mapit x,136,004 ; caret (sigh!!!)
mapit x,137,030 ; underscore
return ; and return
; Flush nulls and bump byte pointer. Assumes that no data bytes follow
; padding bytes in a word.
nulfls: ibp ntibf+1 ; point to byte we're going to hack
move x,@ntibf+1 ; get word of that byte
andx x,17 ; only marking bits
jffo x,.+2 ; count leading zeros
return ; no nulls to flush
andcam x,@ntibf+1 ; turn off padding bits
move y,-32.(y)+[.byte 8 ? 377 ? 377 ? 377 ? 377
.byte 8 ? 000 ? 377 ? 377 ? 377
.byte 8 ? 000 ? 000 ? 377 ? 377
.byte 8 ? 000 ? 000 ? 000 ? 377]
iorm y,@ntibf+1 ; hack out trailing nulls
return ; normal return
subttl Display hacking
dpyser: caxle x,%tdrst ; a baddie?
jrst [ outstr [asciz/Spurious input %TD code (/]
idivx x,100 ; get hundreds
idivx y,10 ; and tens and ones
repeat 3,[
addx x+.rpcnt,"0 ; ASCIIify
outchr x+.rpcnt ; and print it
] ; once for each digit
burp [asciz/) flushed.
/]
jrst ntisr1] ; yes, report it
xct dpyctb-200(x) ; no, dispatch on it
jrst ntisr1 ; return
; Dispatch table for ITS cursor control codes. The server for
; a display code is defined by:
; DPYSVR code,server instruction
; The servers must be in order by their codes!
define dpysvr code,server
ifn .-dpyctb-code+200,.err code is out of order
server
termin
dpyctb: dpysvr %tdmov,[store %fword,govpos]
dpysvr %tdmv1,[store %fword,gtvpos]
dpysvr %tdeof,[call clreof]
dpysvr %tdeol,[call clreol]
dpysvr %tddlf,[call clr1ch]
dpysvr %tdmtf,[burp [asciz/Spurious input %TDMTF flushed.
/]]
dpysvr %tdmtn,[burp [asciz/Spurious input %TDMTN flushed.
/]]
dpysvr %tdcrl,[call terpri]
dpysvr %tdnop,[jfcl]
dpysvr %tdbs,[burp [asciz/Spurious input %TDBS flushed.
/]]
dpysvr %tdlf,[burp [asciz/Spurious input %TDLF flushed.
/]]
dpysvr %tdrcr,[burp [asciz/Spurious input %TDRCR flushed.
/]]
dpysvr %tdors,[call oreset]
dpysvr %tdqot,[burp [asciz/Spurious input %TDQOT flushed.
/]]
dpysvr %tdfs,[call csraos]
dpysvr %tdmv0,[store %fword,gtvpos]
dpysvr %tdclr,[call clrscn]
dpysvr %tdbel,[call bredle]
dpysvr %tdini,[burp [asciz/Spurious input %TDINI flushed.
/]]
dpysvr %tdilp,[store %fword,gtiln]
dpysvr %tddlp,[store %fword,gtdln]
dpysvr %tdicp,[store %fword,gtich]
dpysvr %tddcp,[store %fword,gtdch]
dpysvr %tdbow,[burp [asciz/Spurious input %TDBOW flushed.
/]]
dpysvr %tdrst,[burp [asciz/Spurious input %TDRST flushed.
/]]
subttl Display subroutines
; Note: none of these routines attempt to perform any wraparound if the
; line gets too large; they trust ITS to do all the work. This is okay
; since ITS SUPDUP will die too if the other ITS sends garbage.
; Here to initialize the screen image in core
scrini: store ascii/ /+1,screen,scrend; write blanks throughout screen
movx x,<ascii/
/+1> ; DD type of terpri
movx y,%zeros ; top line
movx z,1 ; blank word
movx a,nlines ; do for number of lines on screen
scrin1: movem z,screen(y) ; zap first word on line
movem z,screen+1(y) ; and second one too
movem x,screen+nwrdln-2(y) ; put terpri at end
movem z,screen+nwrdln-1(y) ; and nothingness after that
addx y,nwrdln ; go to next line
store %zeros,slupdp-1(a) ; line not updated
sojg a,scrin1 ; loop for next line
glnini: store 2,scc+2,scc+2+ngw-1 ; blank graphics word
return ; now return
; Here to store a character on the screen
scstor: move y,vpos ; line position
caxl y,nlines ; gone too far?
jrst [ move y,[screen+nwrdln,,screen]; foo! gotta scroll (sigh)
blt y,screen+scrsiz-nwrdln-1; the big BLT strikes again
store ascii/ /+1,botlin+1,botlin+<nchars/5>
store %fword,saupdp ; I can't believe I updated the WHOLE thing
store nlines-1,vpos,,y ; set vertical position to bottom line
jrst .+1] ; and continue
store %fword,slupdp(y) ; flag this line changed
store %fword,scupdp ; and that there is a change
imulx y,nwrdln ; number words/line
move z,hpos ; x position
caxle z,linel ; greater than line length
jrst [ burp [asciz/Attempt to output a character beyond end of line.
/]
aos hpos ; account for it anyway
return] ; and flush the attempt
idivx z,5 ; word position
addi y,screen+2(z) ; address of word to hack
dpb x,scbytp(z+1) ; save character on screen
aos hpos ; bump X position
return ; and return
; Here to clear the screen
clrscn: store %zeros,vpos ; top line
store %zeros,hpos ; leftmost column
call scrini ; initialize screen
store %fword,saupdp ; updated entire screen
call scnupd ; now update the screen
return ; and return
; Non-insert/delete display subroutines
; Here to clear to EOL
clreol: save hpos ; save horizontal position
cleol1: movx x,<" > ; space in the character
call scstor ; now put it on the screen
move x,hpos ; get the position now
caxg x,linel ; got to EOL yet?
jrst cleol1 ; nope, not done yet
retr hpos ; yup, all done
return ; and return
; Here to delete a character forward
clr1ch: movx x,<" > ; a blank space
move y,vpos ; line position
store %fword,slupdp(y) ; flag this line changed
store %fword,scupdp ; and that a change happened
imulx y,nwrdln ; number of words/line
move z,hpos ; horizonal position
idivx z,5 ; word position
addi y,screen+2(z) ; address to be hacked
dpb x,scbytp(z+1) ; shove character in
return ; and return
; Here to terpri
terpri: store %zeros,hpos ; to beginning of line
aos vpos ; bump vertical position
store %fword,crupdp ; flag cursor has moved
pjrst clreol ; and now clear the line
; Here to breedle
bredle: movx x,%fword ; → own speaker
beep x, ; breedle...
return ; and return
; Here to respond to an output reset
oreset: movx x,↑\ ; escape code
call netoc1 ; send it
movx x,↑P ; ready to send cursor position
call netoc1 ; here it comes...
move x,vpos ; vertical position
call netoc1 ; . . .
move x,hpos ; horizontal position
call netoc1 ; . . .
aos ntoinp ; flush one net interrupt
pjrst netsnd ; force these crufies out
; Here to forespace
csraos: aos hpos ; bump horizontal position
store %fword,crupdp ; flag cursor updated
return ; and return
; Here to clear to EOF
clreof: save hpos ; save current horizontal pos
save vpos ; ditto for vertical
cleof1: call clreol ; clear to end of line
store %zeros,hpos ; now clear all of the lines below
aos x,vpos ; bump to new line
caxge x,nlines ; all done yet?
jrst cleof1 ; nope, kill next line
retr vpos ; get back old vertical position
retr hpos ; and horizontal position
return ; and return
; Line insert/delete
; Here to insert a line
inslin: move a,x ; copy # of lines to hack
insln0: move x,vpos ; load vertical position
imulx x,nwrdln ; make into word counter
addi x,screen ; address of first word of cursor line
cain x,screen+<nlines-1>*nwrdln ; skip unless at bottom line
jrst insln2 ; on bottom, zap it
move y,[screen+<nlines-2>*nwrdln,,screen+<nlines-1>*nwrdln]
insln1: move z,y ; copy pointer
blt z,nwrdln-1(y) ; copy one line
adjsp y,-nwrdln ; offset a line
caie x,(y) ; done yet?
jrst insln1 ; nope
insln2: store ascii/ /+1,2(x) ; blanks
movei y,nwrdln-2-1(x) ; number to do
addx x,3 ; address offset
hrli x,-1(x) ; complete pointer
blt x,(y) ; zak!
sojg a,insln0 ; loop for more lines
store %fword,saupdp ; updated the world
jrst ntisr1 ; and return
; Here to delete a line
dellin: move a,x ; copy # of lines to hack
delln0: move x,vpos ; get vertical position
imulx x,nwrdln ; frobs to do
addi x,screen ; address of first word of cursor line
cain x,screen+<nlines-1>*nwrdln ; at bottom line?
jrst delln1 ; yup, just copy extra line in
movei y,(x) ; make a copy
addx y,nwrdln ; address of next line
hrli x,(y) ; make a BLT pointer
blt x,screen+<nlines-1>*nwrdln-1; copy the lines
delln1: store ascii/ /+1,2(x) ; blanks
movei y,nwrdln-2-1(x) ; number to do
addx x,3 ; address offset
hrli x,-1(x) ; complete pointer
blt x,(y) ; zak!
sojg a,delln0 ; loop for more lines
store %fword,saupdp ; updated the world
jrst ntisr1 ; and return
; Character insert
inschr: move c,a ; copy character counter
insch0: move x,vpos ; get vertical position
imulx x,nwrdln ; now number of words
move a,x ; copy it for hacking
addi a,screen+nwrdln+3 ; address of last text word
move y,hpos ; get horizontal position
idivx y,5 ; make it words
addi x,screen+2(y) ; address of word with cursor
ldb y,[010700,,(x)] ; first character in next word
ldb b,[ 103400,,(x)
102500,,(x)
101600,,(x)
100700,,(x)
100000,,(x)](z)
dpb b,[ 013400,,(x)
012500,,(x)
011600,,(x)
010700,,(x)
010000,,(x)](z)
movx b,<" > ; space in hole
dpb b,[ 350700,,(x)
260700,,(x)
170700,,(x)
100700,,(x)
010700,,(x)](z)
jrst insch1 ; check for being done
; At each iteration Y has last character, X has next address
insch2: move z,y ; copy the character
ldb y,[010700,,(x)] ; first character in next word
dpb z,[000700,,(x)] ; last character here
move z,(x) ; get word being hacked
rot z,-7 ; put characters in right place
iorx z,1 ; make sure bit 1.1 is on
movem z,(x) ; save character in word
insch1: came x,a ; at last address?
aoja x,insch2 ; nope
store %fword,scupdp ; some update somewhere
move x,vpos ; this line
sojg c,insch0 ; loop for more characters
store %fword,slupdp(x) ; this line was hacked
jrst ntisr1 ; and return
; Character delete
delchr: move c,x ; copy number of characters to hack
delch0: move x,vpos ; get current vertical position
imulx x,nwrdln ; number of words
move a,x ; save it for later
addi a,screen+nwrdln-3 ; address of last text word in line
move y,hpos ; get horizontal position
idivx y,5 ; number of words
addi x,screen+2(y) ; address of word with cursor
ldb b,[ 013400,,(x)
012500,,(x)
011600,,(x)
010700,,(x)
010000,,(x)](z)
dpb b,[ 103400,,(x)
102500,,(x)
101600,,(x)
100700,,(x)
100000,,(x)](z)
jrst delch1 ; check for being done
; Each time around the iteration A had address of next word
delch2: ldb y,[350700,,(x)] ; last character in previous
dpb y,[010700,,-1(x)] ; to previous
ldb y,[013400,,(x)] ; get last characters in this word
dpb y,[103400,,(x)] ; put back left justified
delch1: came x,a ; done?
aoja x,delch2 ; not yet
movx y,<" > ; get a space
dpb y,[010700,,(x)] ; blank out last column
store %fword,scupdp ; screen updated someplace
move x,vpos ; get this line
sojg c,delch0 ; hack another character
store %fword,slupdp(x) ; flag this line hacked
jrst ntisr1 ; and return
subttl Display update subroutines
scnupd: skipe slowip ; in slow mode?
jrst scnup1 ; yes, good enough
movx x,<-nlines,,> ; load pointer to line update table
movx y,%zeros ; initialize line count
skipe slupdp(x) ; does this line need hacking?
addx y,1 ; yup, bump count
aobjn x,.-2 ; try for more lines
caxl y,nlnupd ; three lines or so?
store %fword,saupdp ; yup, must update screen
scnup1: aose saupdp ; update entire screen?
jrst scupd1 ; nope, maybe selective
store %zeros,scupdp ; clear other update flags
store %zeros,slupdp,slupdp+nlines-1; . . .
ddupg sdisp ; output new screen
; Update cursor
csrupd: call glnini ; clear cursor line
skipge x,ovpos ; got an old position?
jrst .+3 ; nope, don't try to clear old
call getcsy ; get cursor vertical position
ddupg cdisp ; clear cursor
move x,hpos ; horizontal character position
imulx x,6 ; horizontal bit position
addx x,2 ; graphics mode hack
idivx x,32.
movns y
movx z,(740000)
lsh z,(y)
ldb a,[010300,,z]
rot a,-3
andx z,777777777760
iorx z,2
iorx a,2
movem z,scc+2(x)
movem a,scc+3(x)
move x,vpos ; get current vertical position
movem x,ovpos ; save as old position
call getcsy ; get cursor vertical position
ddupg cdisp ; and send it all out
return ; finally return
scupd1: aose scupdp ; did any update happen?
jrst scupd2 ; nope, try for just cursor
movx x,<-nlines,,> ; load line pointer
scup1a: skipe slupdp(x) ; need to hack this line?
call updlin ; yup
aobjn x,scup1a ; loop for next line
jrst csrupd ; now update cursor
scupd2: aose crupdp ; was cursor hacked
return ; nope, just return
jrst csrupd ; yes, then hack the cursor
; More display updating stuff
; Set up display program vertical position
getcsy: imulx x,12.
addx x,24.+10.
dpb x,[140400,,scc+1]
lsh x,-4
dpb x,[240500,,scc+1]
return ; and return
; Display a single line
updlin: store %zeros,slupdp(x) ; am updating now
hrrz y,x ; line number
imulx y,nwrdln ; word position
addi y,screen ; address of start of line
hrrm y,ldisp ; hack up line display command
movem y,ldisp+3 ; . . .
hrrz z,x ; get line number again
imulx z,12.
addx z,24. ; starting raster number
move a,linprg ; program
dpb z,[140400,,a] ; zap in low 4 bits of address
lsh z,-4 ; throw low bits away
dpb z,[240500,,a] ; high 5 bits of address
movem a,(y) ; save this command
move linpr1 ; go to column 2
movem 1(y) ; save this command
store %zeros,nwrdln-1(y) ; clear word at EOL
ddupg ldisp ; display the line
movx a,1 ; nothingness
movem a,(y) ; zap command
movem a,1(y) ; . . .
aos nwrdln-1(y) ; put back 5 nulls
return ; now return
linprg: ddcmd 1,46,4,0,5,0 ; line update commands
linpr1: ddcmd 3,2,3,2,3,2
subttl SUPDUP commands
cmdcmd: inchrw x ; get command character
caxe x,"s ; slow mode?
caxn x,"S ; . . .
jrst [store %fword,slowip ; yes
outstr [asciz/Entering slow display mode!
/]
jrst ttiser] ; and continue gobbling input
caxe x,"f ; fast mode?
caxn x,"F ; . . .
jrst [store %zeros,slowip ; yes
outstr [asciz/Entering fast display mode!
/]
jrst ttiser] ; and continue hacking
caxe x,"q ; quit?
caxn x,"Q ; . . .
jrst quit ; yup, instant suicide
caxe x,"l ; logout foreign job?
caxn x,"L ; . . .
jrst killer ; it's a killer you know
caxe x,"k ; kill foreign job first?
caxn x,"K ; . . .
killer: jrst [movx x,300 ; escape code
call netoc1 ; prepare for escape
movx x,301 ; kill other job code
call netoc1 ; send it too
call netsnd ; now send this command out
outstr [asciz/Logged out foreign job and /]
jrst quit] ; and die die die
caxe x,"h ; help me?
caxn x,"H ; . . .
caxa ; yup
caxn x,"? ; yet another way to beg for help
jrst [ outstr hlptxt ; give user help text
jrst @ppdisp] ; and show the page printer
caxe x,"r ; record screen?
caxn x,"R ; . . .
jrst record ; yes, write record file
; This command is only for me when debugging, so is not documented!!
caxe x,"d ; enter DDT | RAID?
caxn x,"D ; . . .
jrst [skipn x,jobddt ; is there a DDT?
jrst [ outstr [asciz/No DDT!
/]
jrst @youluz] ; sorry 'bout that
call (x) ; enter DDT
jrst ttiser] ; return from DDT, return to user
; More SUPDUP commands stuff
caxe x,"p ; temporarily restore page printer?
caxn x,"P ; . . .
ppdisp: jrst [outstr [asciz/Type any character to get back to ITS:/]
hrroi x,[004000,,400\"N]; <BREAK>N
ttyset x, ; normalize screen
hrroi x,[004000,,"W] ; <ESCAPE>W
ttyset x, ; restore who-line
movx x,1 ; wait one second...
sleep x, ; ... to let the dust settle
hrroi x,[004000,,"P] ; <ESCAPE>P
ttyset x, ; restore page printer
inchrw x ; get a character
clrbfi ; flush any other input (like CRLF)
outstr [asciz/ [Continued]
/] ; pretty up page printer
ppact 0 ; flush PP 0
leypos 2000 ; line editor off screen
ddupg sclear ; zap screen
hrroi x,[004000,,"W] ; <ESCAPE>W
ttyset x, ; restore who-line quickly
store %fword,saupdp ; must redisplay whole screen
call scnupd ; update screen
store %zeros,ntiinp ; clear output resets
jrst ttiser] ; all done
ldb y,[001000,,x] ; get αcharacter
caxe y,%txctl\"z ; αz or αβz?
caxn y,%txctl\"Z ; αZ or αβZ?
jrst imgsnd ; yes, send it in image form
caxe y,%txctl\"_ ; α_ or αβ_?
youluz: jrst [ movx x,%fword ; to myself
beep x, ; breedle!
jrst ttiser] ; now continue
imgsnd: store %fword,imgchp ; image characters now
call netoch ; send it too
call netsnd ; send it out
jrst ttiser ; and try for another
hlptxt: asciz/
SUPDUP Commands:
F Use Fast display mode (default).
H Type this cruft.
K Kill job at remote host, close connection.
L Same as K.
P Temporarily restore page printer; typing any character restores the
screen to ITS.
Q Detach job at remote host, close connection (quit).
R Write a record of the contents of the screen onto a file; asks you
for the file name.
S Use Slow display mode.
? Same as H.
αz, αβz, αZ, αβZ, α_, and αβ_ are sent as is to the foreign host after a
command instead of being mapped to forms of [CALL] or [BACK NEXT]. Any
other character is illegal and is flushed.
For more information, read SUPDUP.MRC[UP,DOC] or SUPDUP.MID[NET,MRC].
/
subttl Screen record crock
record: open dsk,[17 ? 'DSK,, ? 0] ; get a disk channel
jrst [ burp [asciz/Unable to get a disk channel for recording!
/]
jrst ttiser]
hrroi x,[004000,,400\"N] ; <BREAK>N
ttyset x, ; normalize screen
hrroi x,[004000,,"W] ; <ESCAPE>W
ttyset x, ; restore who-line
movx x,1 ; wait one second...
sleep x, ; ... to let the dust settle
hrroi x,[004000,,"P] ; <ESCAPE>P
ttyset x, ; restore page printer
ptjobx [0 ? sixbit/DON/] ; turn echoing on
txz x,(100) ; special activation mode bit
setlin x ; leave SAM
setact [[777777,,777777 ; activate on 000 - 043
777700,,037600 ; 044 - 107
000000,,374000 ; 110 - 153
000007,,600000]] ; 154 - 177, αβ activate, etc
outstr [asciz/Writing screen record.../]
movx x,<-nlines,,> ; number of lines to write
recrd1: movx y,nwrdln ; number of words to offset
imuli y,(x) ; compute offset from start of screen
addi y,screen+1 ; absolute address of line's characters-1
hrli y,3-nwrdln ; number of character words/line+terpri
movx z,%zeros ; dump mode stop code
out dsk,y ; write line out
aobjn x,recrd1 ; won
jumpl x,[ burp [asciz/Disk OUT failed!
/]
jrst .+1] ; boo
close dsk, ; close off file
release dsk, ; free up channel
ptjobx [0 ? sixbit/DOFF/] ; turn echoing off
getlin x ; get line characteristics
txo x,(100) ; special activation mode bit
setlin x ; enter SAM
setact [[777777,,777777 ; activate on 000 - 043
777777,,777777 ; 044 - 107
777777,,777777 ; 110 - 153
777777,,600066]] ; 154 - 177, αβ activate, etc
ppact 0 ; flush PP 0
leypos 2000 ; line editor off screen
ddupg sclear ; zap screen
hrroi x,[004000,,"W] ; <ESCAPE>W
ttyset x, ; restore who-line quickly
store %fword,saupdp ; must redisplay whole screen
call scnupd ; update screen
store %zeros,ntiinp ; clear output resets
jrst ttiser ; and return
subttl Random routines, literals, etc.
; Here if could not get terminal name; give a random string
rndtid: move y,[440700,,[asciz/Unknown Data Disc/]]
burp [asciz/Unable to get the name of this Data Disc.
/]
sndid1: ildb x,y ; get a character
call netoc1 ; send it
jumpn x,sndid1 ; and continue if not done
jrst tidone ; all done
; Here to get a character from terminal rooms table
getch: 0 ; return PC
sosg dsibf+2 ; buffer ready?
in dsk, ; no, get one then
caxa ; won
jrst rndtid ; lost, send random name
ildb x,dsibf+1 ; get a character
jumpe x,getch+1 ; flush nulls
caxe x,↑M ; hit a terpri?
aos getch ; no, bump return PC
jrst 2,@getch ; now return
; Die when we lose
diedie: burp [asciz/Connection failed.
/]
caxa ; different message
quit: outstr [asciz/Closed connection.
/]
ddupg sclear ; clear user's screen
reset ; restore the world
hrroi x,[004000,,400\"N] ; <BREAK>N
ttyset x, ; restore PP
hrroi x,[004000,,"W] ; <ESCAPE>W
ttyset x, ; restore who-line
exit ; bye bye
; ICP lost
icpluz: outstr [asciz/Failed/]
exit ; bye bye
...lit: variables ; must not have variables!
ifn .-...lit,.err Variables lose lose lose
constants ; generate constants
end SUPDUP